﻿
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

namespace CommandLib
{
    /// <summary>
    /// JSON转换扩展类
    /// </summary>
    public static class JsonConver
    {
        /// <summary>
        ///  将实体对象转为Json字符串
        /// </summary>
        /// <param name="value">要转的值</param>
        /// <param name="isJsonProperty">是否忽略JsonProperty属性名，ture：忽略，false：反之</param>
        /// <param name="DateTimeFormat">时间格式</param>
        /// <returns></returns>
        public static string ToJsonString(this object value, bool isJsonProperty = false, String DateTimeFormat = "yyyy/MM/dd HH:mm:ss")
        {
            string result = string.Empty;
            if (value != null)
            {

                var settings = new JsonSerializerSettings
                {
                    DefaultValueHandling = DefaultValueHandling.Ignore,
                    DateFormatString = DateTimeFormat,
                };
                if (isJsonProperty)
                {
                    settings.ContractResolver = new LongNameContractResolver();
                }
                result = JsonConvert.SerializeObject(value, settings);
            }
            return result;

        }

        /// <summary>
        /// 将字符串转化为对象
        /// </summary>
        /// <typeparam name="T">转换目录对象</typeparam>
        /// <param name="json">JSON字符串</param>
        /// <param name="isJsonProperty">是否忽略JsonProperty属性名，ture：忽略，false：反之</param>
        /// <returns></returns>
        public static T JsonToObject<T>(this string json, bool isJsonProperty = false)
        {
            var result = default(T);
            try
            {
                if (!json.IsEmpty())
                {
                    var settings = new JsonSerializerSettings
                    {
                        DefaultValueHandling = DefaultValueHandling.Ignore,
                    };
                    if (isJsonProperty)
                    {
                        settings.ContractResolver = new LongNameContractResolver();
                    }
                    result = JsonConvert.DeserializeObject<T>(json, settings);
                }

            }
            catch (Exception)
            {
                throw;
            }
            return result;
        }


        /// <summary>
        /// 对象转换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T ObjectToModel<T>(this object value) where T : class, new()
        {
            var result = default(T);
            if (value != null)
            {
                result = value.ToJsonString(true).JsonToObject<T>(true);
            }
            return result;

        }
        /// <summary>
        /// 获取对象属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static T GetPropertyValue<T>(this object value, string name)
        {
            var result = default(T);
            if (value != null && !string.IsNullOrEmpty(name))
            {
                if (value.GetType().Name == "JObject")
                {
                    var json = value as JObject;

                    result = (T)ChangeType(json[name], typeof(T));
                }
                else
                {
                    var ob = value.GetType().GetProperty(name);
                    if (ob != null)
                    {
                        result = (T)ChangeType(ob.GetValue(value), typeof(T));
                    }
                }
            }
            return result;
        }
        public static object ChangeType(object value, Type type)
        {
            if (value == null && type.IsGenericType) return Activator.CreateInstance(type);
            if (value == null) return null;
            if (type == value.GetType()) return value;
            if (type.IsEnum)
            {
                if (value is string)
                    return Enum.Parse(type, value as string);
                else
                    return Enum.ToObject(type, value);
            }
            if (!type.IsInterface && type.IsGenericType)
            {
                Type innerType = type.GetGenericArguments()[0];
                object innerValue = ChangeType(value, innerType);
                return Activator.CreateInstance(type, new object[] { innerValue });
            }
            if (value is string && type == typeof(Guid)) return new Guid(value as string);
            if (value is string && type == typeof(Version)) return new Version(value as string);
            if (!(value is IConvertible)) return value;
            return Convert.ChangeType(value, type);
        }

    }
    public class LongNameContractResolver : DefaultContractResolver
    {
        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
            foreach (JsonProperty prop in list)
            {
                prop.PropertyName = prop.UnderlyingName;
            }
            return list;
        }
    }
}
